import type { Plugin } from 'vite';
import https from 'https';
// import fs from 'fs';
import path from 'path';
import { theme as baseTheme } from '@deepfos/theme';
// @ts-ignore
import LessPluginImportNodeModules from 'less-plugin-import-node-modules';

interface SeeplnConfig {
  // ant 样式前缀，默认 package.json 的 name
  antPrefix?: string;
  // 模式 默认：system
  mode?: 'system' | 'element';
  // 主题变量
  theme?: Record<string, string>;
  // 针对 Pact 调试，需"调用/提供"应用都开启
  pactMode?: boolean;
}

const readManifestSync = async (deepfosEnv: string): Promise<any> => {
  return new Promise((resolve, reject) => {
    // const source = fs.readFileSync(path.resolve(__dirname, '../manifest.json'));
    // resolve(JSON.parse(source.toString()));
    // 读取部署环境的manifest.json, 默认test环境域名
    https.get(`${deepfosEnv}/package-base/manifest.json`, (res) => {
      if (res.statusCode !== 200) {
        reject(new Error(res.statusMessage));
        return;
      }
      let resStr = '';
      res.on('data', (data) => {
        resStr += data;
      }).on('end', () => {
        try {
          const json = JSON.parse(resStr.toString());
          resolve(json);
        } catch (e) {
          resolve({});
        }
      });
    });
  }).catch(() => {
    return {};
  });
};

// 获取package-base打包manifest.json,取得external配置
export async function getExternals(deepfosEnv: string) {
  if (!deepfosEnv) {
    throw new Error('deepfosEnv 环境域名没有设置。')
  }
  const externalNames: string[] = [];
  const externalAliases = {};
  const pkgManifest = await readManifestSync(deepfosEnv);
  if (Array.isArray(pkgManifest?.assets)) {
    pkgManifest?.assets?.forEach(({ name, target }: {
      name: string;
      target: string;
    }) => {
      externalNames.push(name);
      externalAliases[name] = target;
    });
  }
  return {
    externalNames,
    externalAliases
  };
}

// 外部依赖，目的为了兼容 Pact 调试，而保持同一实例
export const externalAlias = {
  react: '/package-base/react17.mjs',
  'react-dom': '/package-base/react-dom17.mjs',
  // 'react-router': '/package-base/react-router',
  'react-router-dom': '/package-base/react-router-dom5.mjs',
  'react-intl': '/package-base/react-intl.mjs',
  'styled-components': '/package-base/styled-components.mjs',
  // history: '/package-base/history', // TODO:package-base里没有直接导出history?具体路径待定
};

// eslint-disable-next-line import/no-dynamic-require
const { name, version } = require(path.join(process.cwd(), 'package.json'));

export default function vitePluginSeepln(config: SeeplnConfig): Plugin {
  return {
    enforce: 'post',
    name: 'seepln',
    config(cfg) {
      return {
        cacheDir: '.tmp',
        resolve: {
          alias: {
            '@/': `${path.resolve(process.cwd(), 'src')}/`,
            lodash: 'lodash-es',
            'lodash.debounce': 'lodash-es/debounce',
            'lodash.throttle': 'lodash-es/throttle',
            ...(config.pactMode && externalAlias),
          },
          extensions: ['.mjs', '.jsx', '.js', '.tsx', '.ts', '.json'],
        },
        server: {
          host: '0.0.0.0',
        },
        css: {
          preprocessorOptions: {
            less: {
              modifyVars: {
                ...baseTheme,
                ...config.theme,
                '@ant-prefix': config.antPrefix || name,
              },
              plugins: [new LessPluginImportNodeModules()],
              javascriptEnabled: true,
            },
          },
        },
        ...(config.mode === 'element' && {
          // pathname 前缀
          base: cfg.base || `/${name}/${version.replace(/\./g, '-')}/`,
        }),
      };
    },

    transform(code: string, id: string) {
      // 修复多个 vite 嵌套 webcomponents 报错的问题
      if (
        process.env.NODE_ENV !== 'production' &&
        id.endsWith('/node_modules/vite/dist/client/client.js')
      ) {
        return {
          code: code.replace(
            /(customElements\.define\(overlayId, ErrorOverlay\))/,
            `!customElements.get(overlayId) && $1`,
          ),
        };
      }
      return null;
    },
  };
}
